home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / sh-utils.12 / sh-utils / sh-utils-1.12 / src / id.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-11  |  8.2 KB  |  378 lines

  1. /* id -- print real and effective UIDs and GIDs
  2.    Copyright (C) 89, 90, 91, 92, 93, 1994 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* Written by Arnold Robbins, arnold@audiofax.com.
  19.    Major rewrite by David MacKenzie, djm@gnu.ai.mit.edu. */
  20.  
  21. #include <config.h>
  22. #include <stdio.h>
  23. #include <getopt.h>
  24. #include <sys/types.h>
  25. #include <pwd.h>
  26. #include <grp.h>
  27. #include <getopt.h>
  28.  
  29. #include "version.h"
  30. #include "system.h"
  31.  
  32. #ifdef _POSIX_VERSION
  33. #include <limits.h>
  34. #if !defined(NGROUPS_MAX) || NGROUPS_MAX < 1
  35. #undef NGROUPS_MAX
  36. #define NGROUPS_MAX sysconf (_SC_NGROUPS_MAX)
  37. #endif /* !NGROUPS_MAX */
  38.  
  39. #else /* not _POSIX_VERSION */
  40. struct passwd *getpwuid ();
  41. struct group *getgrgid ();
  42. uid_t getuid ();
  43. gid_t getgid ();
  44. uid_t geteuid ();
  45. gid_t getegid ();
  46. #include <sys/param.h>
  47. #if !defined(NGROUPS_MAX) && defined(NGROUPS)
  48. #define NGROUPS_MAX NGROUPS
  49. #endif /* not NGROUPS_MAX and NGROUPS */
  50. #endif /* not _POSIX_VERSION */
  51.  
  52. char *xmalloc ();
  53. int getugroups ();
  54. void error ();
  55.  
  56. static void print_user ();
  57. static void print_group ();
  58. static void print_group_list ();
  59. static void print_full_info ();
  60. static void usage ();
  61.  
  62. /* The name this program was run with. */
  63. char *program_name;
  64.  
  65. /* If nonzero, output only the group ID(s). -g */
  66. static int just_group = 0;
  67.  
  68. /* If nonzero, output user/group name instead of ID number. -n */
  69. static int use_name = 0;
  70.  
  71. /* If nonzero, output real UID/GID instead of default effective UID/GID. -r */
  72. static int use_real = 0;
  73.  
  74. /* If nonzero, output only the user ID(s). -u */
  75. static int just_user = 0;
  76.  
  77. /* If nonzero, output only the supplementary groups. -G */
  78. static int just_group_list = 0;
  79.  
  80. /* The real and effective IDs of the user to print. */
  81. static uid_t ruid, euid;
  82. static gid_t rgid, egid;
  83.  
  84. /* The number of errors encountered so far. */
  85. static int problems = 0;
  86.  
  87. /* If non-zero, display usage information and exit.  */
  88. static int show_help;
  89.  
  90. /* If non-zero, print the version on standard output and exit.  */
  91. static int show_version;
  92.  
  93. static struct option const longopts[] =
  94. {
  95.   {"group", no_argument, NULL, 'g'},
  96.   {"groups", no_argument, NULL, 'G'},
  97.   {"help", no_argument, &show_help, 1},
  98.   {"name", no_argument, NULL, 'n'},
  99.   {"real", no_argument, NULL, 'r'},
  100.   {"user", no_argument, NULL, 'u'},
  101.   {"version", no_argument, &show_version, 1},
  102.   {NULL, 0, NULL, 0}
  103. };
  104.  
  105. void
  106. main (argc, argv)
  107.      int argc;
  108.      char **argv;
  109. {
  110.   int optc;
  111.  
  112.   program_name = argv[0];
  113.  
  114.   while ((optc = getopt_long (argc, argv, "gnruG", longopts, (int *) 0))
  115.      != EOF)
  116.     {
  117.       switch (optc)
  118.     {
  119.     case 0:
  120.       break;
  121.     case 'g':
  122.       just_group = 1;
  123.       break;
  124.     case 'n':
  125.       use_name = 1;
  126.       break;
  127.     case 'r':
  128.       use_real = 1;
  129.       break;
  130.     case 'u':
  131.       just_user = 1;
  132.       break;
  133.     case 'G':
  134.       just_group_list = 1;
  135.       break;
  136.     default:
  137.       usage (1);
  138.     }
  139.     }
  140.  
  141.   if (show_version)
  142.     {
  143.       printf ("id - %s\n", version_string);
  144.       exit (0);
  145.     }
  146.  
  147.   if (show_help)
  148.     usage (0);
  149.  
  150.   if (just_user + just_group + just_group_list > 1)
  151.     error (1, 0, "cannot print only user and only group");
  152.  
  153.   if (just_user + just_group + just_group_list == 0 && (use_real || use_name))
  154.     error (1, 0, "cannot print only names or real IDs in default format");
  155.  
  156.   if (argc - optind > 1)
  157.     usage (1);
  158.  
  159.   if (argc - optind == 1)
  160.     {
  161.       struct passwd *pwd = getpwnam (argv[optind]);
  162.       if (pwd == NULL)
  163.     error (1, 0, "%s: No such user", argv[optind]);
  164.       ruid = euid = pwd->pw_uid;
  165.       rgid = egid = pwd->pw_gid;
  166.     }
  167.   else
  168.     {
  169.       euid = geteuid ();
  170.       ruid = getuid ();
  171.       egid = getegid ();
  172.       rgid = getgid ();
  173.     }
  174.  
  175.   if (just_user)
  176.     print_user (use_real ? ruid : euid);
  177.   else if (just_group)
  178.     print_group (use_real ? rgid : egid);
  179.   else if (just_group_list)
  180.     print_group_list (argv[optind]);
  181.   else
  182.     print_full_info (argv[optind]);
  183.   putchar ('\n');
  184.  
  185.   exit (problems != 0);
  186. }
  187.  
  188. /* Print the name or value of user ID UID. */
  189.  
  190. static void
  191. print_user (uid)
  192.      int uid;
  193. {
  194.   struct passwd *pwd = NULL;
  195.  
  196.   if (use_name)
  197.     {
  198.       pwd = getpwuid (uid);
  199.       if (pwd == NULL)
  200.     problems++;
  201.     }
  202.  
  203.   if (pwd == NULL)
  204.     printf ("%u", (unsigned) uid);
  205.   else
  206.     printf ("%s", pwd->pw_name);
  207. }
  208.  
  209. /* Print the name or value of group ID GID. */
  210.  
  211. static void
  212. print_group (gid)
  213.      int gid;
  214. {
  215.   struct group *grp = NULL;
  216.  
  217.   if (use_name)
  218.     {
  219.       grp = getgrgid (gid);
  220.       if (grp == NULL)
  221.     problems++;
  222.     }
  223.  
  224.   if (grp == NULL)
  225.     printf ("%u", (unsigned) gid);
  226.   else
  227.     printf ("%s", grp->gr_name);
  228. }
  229.  
  230. /* Print all of the distinct groups the user is in . */
  231.  
  232. static void
  233. print_group_list (username)
  234.      char *username;
  235. {
  236.   print_group (rgid);
  237.   if (egid != rgid)
  238.     {
  239.       putchar (' ');
  240.       print_group (egid);
  241.     }
  242.  
  243. #if defined(NGROUPS_MAX) && defined(HAVE_GETGROUPS)
  244.   {
  245.     int ngroups;
  246.     GETGROUPS_T *groups;
  247.     register int i;
  248.  
  249.     groups = (GETGROUPS_T *) xmalloc (NGROUPS_MAX * sizeof (GETGROUPS_T));
  250.     if (username == 0)
  251.       ngroups = getgroups (NGROUPS_MAX, groups);
  252.     else
  253.       ngroups = getugroups (NGROUPS_MAX, groups, username);
  254.     if (ngroups < 0)
  255.       {
  256.     error (0, errno, "cannot get supplemental group list");
  257.     problems++;
  258.     free (groups);
  259.     return;
  260.       }
  261.  
  262.     for (i = 0; i < ngroups; i++)
  263.       if (groups[i] != rgid && groups[i] != egid)
  264.     {
  265.       putchar (' ');
  266.       print_group (groups[i]);
  267.     }
  268.     free (groups);
  269.   }
  270. #endif
  271. }
  272.  
  273. /* Print all of the info about the user's user and group IDs. */
  274.  
  275. static void
  276. print_full_info (username)
  277.      char *username;
  278. {
  279.   struct passwd *pwd;
  280.   struct group *grp;
  281.  
  282.   printf ("uid=%u", (unsigned) ruid);
  283.   pwd = getpwuid (ruid);
  284.   if (pwd == NULL)
  285.     problems++;
  286.   else
  287.     printf ("(%s)", pwd->pw_name);
  288.   
  289.   printf (" gid=%u", (unsigned) rgid);
  290.   grp = getgrgid (rgid);
  291.   if (grp == NULL)
  292.     problems++;
  293.   else
  294.     printf ("(%s)", grp->gr_name);
  295.   
  296.   if (euid != ruid)
  297.     {
  298.       printf (" euid=%u", (unsigned) euid);
  299.       pwd = getpwuid (euid);
  300.       if (pwd == NULL)
  301.     problems++;
  302.       else
  303.     printf ("(%s)", pwd->pw_name);
  304.     }
  305.   
  306.   if (egid != rgid)
  307.     {
  308.       printf (" egid=%u", (unsigned) egid);
  309.       grp = getgrgid (egid);
  310.       if (grp == NULL)
  311.     problems++;
  312.       else
  313.     printf ("(%s)", grp->gr_name);
  314.     }
  315.  
  316. #if defined(NGROUPS_MAX) && defined(HAVE_GETGROUPS)
  317.   {
  318.     int ngroups;
  319.     GETGROUPS_T *groups;
  320.     register int i;
  321.  
  322.     groups = (GETGROUPS_T *) xmalloc (NGROUPS_MAX * sizeof (GETGROUPS_T));
  323.     if (username == 0)
  324.       ngroups = getgroups (NGROUPS_MAX, groups);
  325.     else
  326.       ngroups = getugroups (NGROUPS_MAX, groups, username);
  327.     if (ngroups < 0)
  328.       {
  329.     error (0, errno, "cannot get supplemental group list");
  330.     problems++;
  331.     free (groups);
  332.     return;
  333.       }
  334.  
  335.     if (ngroups > 0)
  336.       fputs (" groups=", stdout);
  337.     for (i = 0; i < ngroups; i++)
  338.       {
  339.     if (i > 0)
  340.       putchar (',');
  341.     printf ("%u", (unsigned) groups[i]);
  342.     grp = getgrgid (groups[i]);
  343.     if (grp == NULL)
  344.       problems++;
  345.     else
  346.       printf ("(%s)", grp->gr_name);
  347.       }
  348.     free (groups);
  349.   }
  350. #endif
  351. }
  352.  
  353. static void
  354. usage (status)
  355.      int status;
  356. {
  357.   if (status != 0)
  358.     fprintf (stderr, "Try `%s --help' for more information.\n",
  359.          program_name);
  360.   else
  361.     {
  362.       printf ("Usage: %s [OPTION]... [USERNAME]\n", program_name);
  363.       printf ("\
  364. \n\
  365.   -g, --group     print only the group ID\n\
  366.   -G, --groups    print only the supplementary groups\n\
  367.   -n, --name      print a name instead of a number, for -ugG\n\
  368.   -r, --real      print the real ID instead of effective ID, for -ugG\n\
  369.   -u, --user      print only the user ID\n\
  370.       --help      display this help and exit\n\
  371.       --version   output version information and exit\n\
  372. \n\
  373. Without any OPTION, print some useful set of identified information.\n\
  374. ");
  375.     }
  376.   exit (status);
  377. }
  378.